﻿using Dapper_Core.Model;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.IO;
using System.Net;
using System.Text;
using System.Threading.Tasks;

namespace Dapper_Core.Common
{
    public class HttpUtility
    {
        public static string Get(string url, NameValueCollection headers, CookieContainer cookieContainer)
        {
            try
            {
                //ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
                Encoding encoding = Encoding.UTF8;
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                request.Method = "GET";
                request.Accept = "application/json";
                request.Proxy = null;
                if (cookieContainer != null)
                {
                    request.CookieContainer = cookieContainer;
                }
                if (headers != null)
                {
                    request.Headers.Add(headers);
                }
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
                {
                    return reader.ReadToEnd();
                }
            }
            catch (Exception ex)
            {
                NlogUtility.WriteError(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName, "后台发起Get请求出现异常", "url=" + url + "，headers=" + headers, ex, "DapperCore");
                throw ex;
            }
        }

        public static async Task<string> GetAsync(string url, NameValueCollection headers, CookieContainer cookieContainer)
        {
            try
            {
                //ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
                Encoding encoding = Encoding.UTF8;
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                request.Method = "GET";
                request.Accept = "application/json";
                request.Proxy = null;
                if (cookieContainer != null)
                {
                    request.CookieContainer = cookieContainer;
                }
                if (headers != null)
                {
                    request.Headers.Add(headers);
                }
                var response = await request.GetResponseAsync();
                using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
                {
                    return reader.ReadToEnd();
                }
            }
            catch (Exception ex)
            {
                NlogUtility.WriteError(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName, "后台发起Get请求出现异常", "url=" + url + "，headers=" + headers, ex, "DapperCore");
                throw ex;
            }
        }

        public static string Get(string url, NameValueCollection headers, ref CookieContainer cookieContainer)
        {
            try
            {
                //ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
                Encoding encoding = Encoding.UTF8;
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                request.Method = "GET";
                request.Accept = "application/json";
                request.Proxy = null;
                if (headers != null)
                {
                    request.Headers.Add(headers);
                }
                request.CookieContainer = new CookieContainer();
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                cookieContainer.Add(response.Cookies);
                using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
                {
                    return reader.ReadToEnd();
                }
            }
            catch (Exception ex)
            {
                NlogUtility.WriteError(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName, "后台发起Get请求出现异常", "url=" + url + "，headers=" + headers, ex, "DapperCore");
                throw ex;
            }
        }

        /// <summary>
        /// HttpPost请求
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <param name="body">字典value优先使用string类型</param>
        /// <param name="headers">请求头</param>
        /// <param name="cookieContainer">cookie值</param>
        /// <param name="contentType">contentType类型</param>
        /// <returns></returns>
        public static string Post(string url, Dictionary<string, object> body, NameValueCollection headers, CookieContainer cookieContainer, string contentType = "application/json")
        {
            string strBody = "";
            if (string.Equals(contentType, ContentType.Json, StringComparison.OrdinalIgnoreCase)) 
            {
                strBody = JsonConvert.SerializeObject(body);
            }
            else if(string.Equals(contentType, ContentType.Form, StringComparison.OrdinalIgnoreCase))
            {
                strBody = GetFormParam(body);
            }
            return Post(url, strBody, headers, cookieContainer, contentType);
        }

        public static string Post(string url, string body, NameValueCollection headers, CookieContainer cookieContainer, string contentType = "application/json")
        {
            try
            {
                //ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
                Encoding encoding = Encoding.UTF8;
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                request.Method = "POST";
                request.Accept = "application/json";
                if (IsValidContentType(contentType))
                {
                    request.ContentType = contentType;
                }
                request.Proxy = null;
                if (cookieContainer != null)
                {
                    request.CookieContainer = cookieContainer;
                }
                if (headers != null)
                {
                    request.Headers.Add(headers);
                }
                byte[] buffer = encoding.GetBytes(body);
                request.ContentLength = buffer.Length;
                request.GetRequestStream().Write(buffer, 0, buffer.Length);
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
                {
                    return reader.ReadToEnd();
                }
            }
            catch (Exception ex)
            {
                NlogUtility.WriteError(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName, "后台发起Post请求出现异常", "url=" + url + "，body=" + body + "，headers=" + headers, ex, "DapperCore");
                throw ex;
            }
        }

        /// <summary>
        /// 异步HttpPost请求
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <param name="body">字典value优先使用string类型</param>
        /// <param name="headers">请求头</param>
        /// <param name="cookieContainer">cookie值</param>
        /// <param name="contentType">contentType类型</param>
        /// <returns></returns>
        public static async Task<string> PostAsync(string url, Dictionary<string, object> body, NameValueCollection headers, CookieContainer cookieContainer, string contentType = "application/json")
        {
            string strBody = "";
            if (string.Equals(contentType, ContentType.Json, StringComparison.OrdinalIgnoreCase))
            {
                strBody = JsonConvert.SerializeObject(body);
            }
            else if (string.Equals(contentType, ContentType.Form, StringComparison.OrdinalIgnoreCase))
            {
                strBody = GetFormParam(body);
            }
            return await PostAsync(url, strBody, headers, cookieContainer, contentType);
        }

        public static async Task<string> PostAsync(string url, string body, NameValueCollection headers, CookieContainer cookieContainer, string contentType = "application/json")
        {
            try
            {
                //ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
                Encoding encoding = Encoding.UTF8;
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                request.Method = "POST";
                request.Accept = "application/json";
                if (IsValidContentType(contentType))
                {
                    request.ContentType = contentType;
                }
                request.Proxy = null;
                if (cookieContainer != null)
                {
                    request.CookieContainer = cookieContainer;
                }
                if (headers != null)
                {
                    request.Headers.Add(headers);
                }
                byte[] buffer = encoding.GetBytes(body);
                request.ContentLength = buffer.Length;
                request.GetRequestStream().Write(buffer, 0, buffer.Length);
                var response = await request.GetResponseAsync();
                using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
                {
                    return reader.ReadToEnd();
                }
            }
            catch (Exception ex)
            {
                NlogUtility.WriteError(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName, "后台发起Post请求出现异常", "url=" + url + "，body=" + body + "，headers=" + headers, ex, "DapperCore");
                throw ex;
            }
        }

        /// <summary>
        /// HttpPost请求
        /// </summary>
        /// <param name="url">请求地址</param>
        /// <param name="body">字典value优先使用string类型</param>
        /// <param name="headers">请求头</param>
        /// <param name="cookieContainer">cookie值</param>
        /// <param name="contentType">contentType类型</param>
        /// <returns></returns>
        public static string Post(string url, Dictionary<string, object> body, NameValueCollection headers, ref CookieContainer cookieContainer, string contentType = "application/json") 
        {
            string strBody = "";
            if (string.Equals(contentType, ContentType.Json, StringComparison.OrdinalIgnoreCase))
            {
                strBody = JsonConvert.SerializeObject(body);
            }
            else if (string.Equals(contentType, ContentType.Form, StringComparison.OrdinalIgnoreCase))
            {
                strBody = GetFormParam(body);
            }
            return Post(url, strBody, headers, ref cookieContainer, contentType);
        }

        public static string Post(string url, string body, NameValueCollection headers, ref CookieContainer cookieContainer, string contentType = "application/json")
        {
            try
            {
                //ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);
                Encoding encoding = Encoding.UTF8;
                HttpWebRequest request = (HttpWebRequest)WebRequest.Create(url);
                request.Method = "POST";
                request.Accept = "application/json";
                if (IsValidContentType(contentType))
                {
                    request.ContentType = contentType;
                }
                request.Proxy = null;
                if (headers != null)
                {
                    request.Headers.Add(headers);
                }
                byte[] buffer = encoding.GetBytes(body);
                request.ContentLength = buffer.Length;
                request.CookieContainer = new CookieContainer();
                request.GetRequestStream().Write(buffer, 0, buffer.Length);
                HttpWebResponse response = (HttpWebResponse)request.GetResponse();
                cookieContainer.Add(response.Cookies);
                using (StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8))
                {
                    return reader.ReadToEnd();
                }
            }
            catch (Exception ex)
            {
                NlogUtility.WriteError(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType.FullName, "后台发起Post请求出现异常", "url=" + url + "，body=" + body + "，headers=" + headers, ex, "DapperCore");
                throw ex;
            }
        }

        /// <summary>
        /// contentType是否合法
        /// </summary>
        /// <param name="contentType"></param>
        /// <returns></returns>
        private static bool IsValidContentType(string contentType)
        {
            return string.Equals(contentType, ContentType.Form, StringComparison.OrdinalIgnoreCase) || string.Equals(contentType, ContentType.Json, StringComparison.OrdinalIgnoreCase);
        }

        /// <summary>
        /// 获取form提交字符串类型的参数
        /// </summary>
        /// <param name="body"></param>
        /// <returns></returns>
        private static string GetFormParam(Dictionary<string, object> body)
        {
            if (body == null || body.Count == 0) return "";
            string param = "";
            foreach (string key in body.Keys)
            {
                if (param.IsEmpty())
                { 
                    param = key + "=" + body[key]; 
                }
                else
                {
                    param = param + "&" + key + "=" + body[key];
                }
            }
            return param;
        }
    }
}
